package com.thx.file.action;

import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.util.Arrays;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.imgscalr.Scalr;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.thx.common.struts2.BaseAction;
import com.thx.common.util.AppContext;
import com.thx.common.util.FileUtil;
import com.thx.common.util.ImgUtil;
import com.thx.file.model.File;
import com.thx.file.service.FileManager;
import com.thx.file.util.WebFileUtil;

@Namespace("/sys")
@Action(value = "file")
@Controller
@Scope("prototype")
public class FileAction extends BaseAction {
  private static final long serialVersionUID = 6625749424673034439L;
  private static final String MODE_AUTO = "auto";
  private static final String MODE_WIDTH = "width";
  private static final String MODE_HEIGHT = "height";
  private static final String MODE_EXACT = "exact";

  @Autowired
  private FileManager fileManager;

  private String fileId;

  private int width;

  private int height;
  /**
   * resize 的模式 auto 自动 按比例计算 width 匹配宽 height 匹配高 exact 完全匹配
   */
  private String mode;


  private java.io.File imgFile;

  private String imgFileFileName;

  public void download() throws IOException {
    if (StringUtils.isNotBlank(fileId)) {
      logger.debug("fileID不为空");
      File file = fileManager.get(fileId);
      if (file != null) {
        logger.debug("file不为空");
        try {
          java.io.File destFile = new java.io.File(file.getPath());
          // --respone的设置
          HttpServletResponse response = getResponse();
          response.reset(); // 非常重要
          response.setCharacterEncoding("utf-8");
          response.setContentType(FileUtil.getMimeType(destFile));

          String agent = getRequest().getHeader("User-agent").toUpperCase();
          String fileName = "";
          if (agent.indexOf("OPERA") > 0) {
            fileName = "filename*=UTF-8''" + file.getOldName();// IE浏览器
          } else if (agent.indexOf("SAFARI") > 0 || agent.indexOf("CHROME") > 0
              || agent.indexOf("FIREFOX") > 0) {
            fileName = "filename=" + new String(file.getOldName().getBytes("UTF-8"), "ISO8859-1");
          } else {
            fileName = "filename=" + URLEncoder.encode(file.getOldName(), "UTF8");
          }
          response.setHeader("Content-Disposition", "attachment;" + fileName);
          boolean isResize = isResize(destFile);
          if (isResize) {
            // --查找是否存在匹配尺寸的图片
            boolean exsit = isExsit(file);
            if (!exsit) {
              file.setPath(destFile.getPath());
              destFile = resize(destFile, file);
            } else {
              destFile = new java.io.File(file.getPath());
            }
          }
          response.setContentLength((int) destFile.length());
          BufferedInputStream br = new BufferedInputStream(new FileInputStream(destFile));
          byte[] buf = new byte[1024];
          int len = 0;
          OutputStream out = response.getOutputStream();
          while ((len = br.read(buf)) > 0)
            out.write(buf, 0, len);
          br.close();
          out.close();
        } catch (FileNotFoundException e) {
          logger.debug("文件路径找不到" + file.getPath(), e);
          getResponse().sendError(404, "File not found!");
          return;
        }

      } else {
        logger.debug("file为空");
        getResponse().sendError(404, "File not found!");
        return;

      }
    }
  }

  public java.io.File getImgFile() {
    return imgFile;
  }

  public void setImgFile(java.io.File imgFile) {
    this.imgFile = imgFile;
  }

  public String getImgFileFileName() {
    return imgFileFileName;
  }

  public void setImgFileFileName(String imgFileFileName) {
    this.imgFileFileName = imgFileFileName;
  }


  public String uploadImg() {

    // 定义允许上传的文件后缀名
    String[] fileTypes = new String[] {"gif", "jpg", "jpeg", "png", "bmp"};
    // 最大文件大小
    long maxSize = 2 * 1024 * 1024;

    HttpServletResponse response = ServletActionContext.getResponse();
    response.setContentType("text/html; charset=UTF-8");
    PrintWriter out = null;
    try {
      out = response.getWriter();
    } catch (IOException e) {
      logger.error("上传图片", e);
    }

    if (imgFile == null) {
      out.println(getError("请选择文件。"));
      return null;
    }

    String extName = FileUtil.getExtName(imgFileFileName).toLowerCase();
    if (!Arrays.<String>asList(fileTypes).contains(extName)) {
      out.println(getError("上传文件后缀名[" + extName + "]是不允许的后缀名。"));
      return null;
    }
    if (imgFile.length() > maxSize) {
      out.println(getError("[ " + imgFileFileName + " ]超过单个文件大小限制，文件大小[ " + imgFile.length()
          + " ]，限制为[ " + maxSize + " ] "));
      return null;
    }
    String baseUrl = AppContext.getProperties("imageBaseUrl");
    String url = WebFileUtil.uploadFile(imgFileFileName, imgFile,baseUrl);
    if (StringUtils.isBlank(url)) {
      out.println(getError("上传失败！"));
    } else {
      JSONObject obj = new JSONObject();
      obj.put("error", 0);
      obj.put("url", url);
      out.println(obj.toString());
    }

    return null;
  }

  private String getError(String message) {
    JSONObject obj = new JSONObject();
    try {
      obj.put("error", 1);
      obj.put("message", message);
    } catch (JSONException e) {
      logger.error(e.getMessage(), e);
    }
    return obj.toString();
  }

  public String getFileId() {
    return fileId;
  }

  public void setFileId(String fileId) {
    this.fileId = fileId;
  }

  public int getWidth() {
    return width;
  }

  public void setWidth(int width) {
    this.width = width;
  }

  public int getHeight() {
    return height;
  }

  public void setHeight(int height) {
    this.height = height;
  }

  public String getMode() {
    return mode;
  }

  public void setMode(String mode) {
    this.mode = mode;
  }

  private boolean isResize(java.io.File file) {
    if (width > 0 || height > 0) {
      return ImgUtil.isImage(file);
    }
    return false;
  }

  private boolean isExsit(File file) {
    if (width <= 0 && height <= 0) {
      return false;
    } else if (width > 0 && height > 0) {
      getScalrModeAndReName(mode, file, width, height);
    } else if (width <= 0 && height > 0) {
      getScalrModeAndReName(mode, file, height);
    } else if (height <= 0 && width > 0) {
      getScalrModeAndReName(mode, file, width);
    }
    java.io.File ioFile = new java.io.File(file.getPath());
    return ioFile.exists();
  }

  private java.io.File resize(java.io.File ioFile, File file) throws IOException {
    if (!ImgUtil.isImage(ioFile)) {
      return ioFile;
    }
    BufferedImage im = ImageIO.read(ioFile);
    if (im != null) {
      if (width > 0 && height > 0) {
        im = Scalr.resize(im, getScalrModeAndReName(mode, file, width, height), width, height);
      } else if (width <= 0 && height > 0) {
        im = Scalr.resize(im, getScalrModeAndReName(mode, file, height), height);
      } else if (height <= 0 && width > 0) {
        im = Scalr.resize(im, getScalrModeAndReName(mode, file, width), width);
      } else {
        return ioFile;
      }
    }
    java.io.File destFile = new java.io.File(file.getPath());
    file.setPath(ioFile.getPath());
    FileOutputStream out = new FileOutputStream(destFile);
    ImageIO.write(im, FileUtil.getExtName(ioFile.getName()), out);
    out.flush();
    out.close();
    return destFile;
  }

  private Scalr.Mode getScalrModeAndReName(String mode, File file, int... size) {
    String newPath = file.getPath();
    String extName = "";
    Scalr.Mode sMode = null;
    if (StringUtils.isNotBlank(newPath) && newPath.lastIndexOf(".") >= 0) {
      extName = newPath.substring(newPath.lastIndexOf("."));
      newPath = newPath.substring(0, newPath.lastIndexOf(".")) + "_r";
    }
    if (MODE_WIDTH.equalsIgnoreCase(mode)) {
      newPath += "_w";
      sMode = Scalr.Mode.FIT_TO_WIDTH;
    }
    if (MODE_HEIGHT.equalsIgnoreCase(mode)) {
      newPath += "_h";
      sMode = Scalr.Mode.FIT_TO_HEIGHT;
    }
    if (MODE_EXACT.equalsIgnoreCase(mode)) {
      newPath += "_e";
      sMode = Scalr.Mode.FIT_EXACT;
    }
    if (sMode == null || MODE_AUTO.equalsIgnoreCase(mode)) {
      newPath += "_a";
      sMode = Scalr.Mode.AUTOMATIC;
    }

    if (size != null) {
      for (int i : size) {
        newPath += "_" + i;
      }
    }
    file.setPath(newPath + extName);
    return sMode;
  }
}
